package main

import (
	"bufio"
	"fmt"
	"google.golang.org/grpc"
	"io"
	"log"
	"net"
	"os"
	"strconv"
	"stream_file_s/consul"
	"stream_file_s/pb"
	"strings"
)

type server struct {
	pb.UnimplementedFileServer
}

func main() {
	//监听
	lis, err := net.Listen("tcp", ":8896")
	if err != nil {
		log.Printf("net.Listen failed,err:%v\n", err)
		return
	}
	//创建服务
	s := grpc.NewServer()
	//注册服务
	pb.RegisterFileServer(s, &server{})

	//程序启动之前要启动注册服务
	myCon, err := consul.New("127.0.0.1:8500")
	if err != nil {
		log.Printf("consul.New failed:%v\n", err)
		return
	}
	//注册
	//ip, _ := consul.GetOutboundIP()
	//fmt.Println(ip)
	err = myCon.RegisterService("upload", "192.168.1.7", 8896)
	if err != nil {
		log.Printf("myCon.RegisterService :%v\n", err)
	}
	//启动服务
	err = s.Serve(lis)
	if err != nil {
		fmt.Printf("grpc start failed,err: %v\n", err)
	}
}
func (s *server) UploadFile(stream pb.File_UploadFileServer) error {
	for {
		fmt.Println("等待链接...")
		//向客户端发送消息
		stream.Send(&pb.UploadResponse{
			Reply: []byte("已连接..."),
		})
		//获取发过来的命令以及大小和文件名
		// 接收流式请求
		in, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		} //向客户端发送消息
		stream.Send(&pb.UploadResponse{
			Reply: []byte("文件接收准备就绪..."),
		})
		//获取文件名和命令"input&" + name + "&" + sizeString
		l := in.GetOther()
		params := strings.Split(l, "&") //向客户端发送消息
		stream.Send(&pb.UploadResponse{
			Reply: []byte("您要上传的文件" + params[1:][0] + ",文件大小:" + params[1:][1] + "..."),
		})
		//命令
		cmd := params[0]
		switch cmd {
		case "input":
			//将文件大小传进去
			upload(stream, params[1:])
		}
	}
}
func upload(stream pb.File_UploadFileServer, params []string) {
	name := params[0]
	size, _ := strconv.Atoi(params[1])
	//设置已读大小
	var readSize int
	//创建或追加文件写入
	file, err := os.OpenFile("uploads/"+name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	if err != nil {
		log.Fatal("err111", err)
	}
	write := bufio.NewWriter(file)
	for readSize < size {
		in, err := stream.Recv()
		if err == io.EOF {
			return
		}
		if err != nil {
			return
		}
		l := in.GetLine()

		//开始进行数据写入
		_, err = write.Write(l)
		if err != nil {
			log.Fatal("写入err", err)
		}
		write.Flush()
		//数据写入结束
		readSize += len(l)
		/*		num1, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", float64(readSize)/float64(size)), 64) // 保留2位小数
				per := num1 * 100
				stream.Send(&pb.UploadResponse{
					Reply: []byte("已上传" + fmt.Sprintf("%f", per) + "%"),
				})*/

	}
	fmt.Println("文件上传成功")
}
